﻿using Mozi.HttpEmbedded;
using Mozi.Live.RTP;
using System;

namespace Mozi.Live
{
    /// <summary>
    /// RTP数据传输控制服务端
    /// </summary>
    public class RTCPServer
    {
        /// <summary>
        /// 最大数据包尺寸 包含所有头信息和有效荷载 Byte
        /// </summary>
        private int _maxTransferPackSize = 512;

        private ulong _packetSendCount, _totalSendBytes, _packetReceived = 0, _totalReceivedBytes;

        protected UDPSocketIOCP _socket;

        protected int _port = 3005;
        /// <summary>
        /// 数据包接收事件，字节流数据包
        /// </summary>
        public DatagramReceive DatagramReceived;
        /// <summary>
        /// 数据报文接收事件
        /// </summary>
        public RTCPMessageTransmit MessageReceived;
        /// <summary>
        /// 数据报文发送事件
        /// </summary>
        public RTCPMessageTransmit MessageSend;
        /// <summary>
        /// 服务端口
        /// </summary>
        public int Port { get { return _port; } protected set { _port = value; } }
        /// <summary>
        /// 启动时间
        /// </summary>
        public DateTime StartTime { get; private set; }
        /// <summary>
        /// 服务器运行状态
        /// </summary>
        public bool Running{ get; set; }
        /// <summary>
        /// 最大数据包尺寸 包含所有头信息和有效荷载
        /// </summary>
        internal int MaxTransferPackSize { get => _maxTransferPackSize; set => _maxTransferPackSize = value; }
        /// <summary>
        /// 累计接收到的包的数量
        /// </summary>
        public ulong PacketReceivedCount { get => _packetReceived; }
        /// <summary>
        /// 累计接收的字节数
        /// </summary>
        public ulong TotalReceivedBytes { get => _totalReceivedBytes; }
        /// <summary>
        /// 累计发出的包的数量
        /// </summary>
        public ulong PacketSendCount => _packetSendCount;
        /// <summary>                                                               
        /// 累计发出的字节数                                                                
        /// </summary>
        public ulong TotalSendBytes => _totalSendBytes;
        /// <summary>
        /// 构造实例
        /// </summary>
        public RTCPServer()
        {
            _socket = new UDPSocketIOCP();
            _socket.AfterReceiveEnd += Socket_AfterReceiveEnd;
        }
        /// <summary>
        /// 以指定端口启动<see cref="F:Port"/>，如果不配置端口则使用默认端口
        /// </summary>
        public void Start()
        {
            Start(_port);
        }
        /// <summary>
        /// 启动本端服务
        /// </summary>
        /// <param name="port"></param>
        public void Start(int port)
        {
            _port = port;
            _socket.Start(_port);
            StartTime = DateTime.Now;
            Running = true;
            Console.WriteLine($"RTCP running on {_socket.SocketMain.LocalEndPoint}");
        }
        /// <summary>
        /// 端口下线
        /// </summary>
        public void Shutdown()
        {
            _socket.Shutdown();
            StartTime = DateTime.MinValue;
            Running = false;
        }
        /// <summary>
        /// 数据接收完成回调
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        /// <remarks>继承类如果覆盖该事件，则可以接管数据处理</remarks>
        protected virtual void Socket_AfterReceiveEnd(object sender, DataTransferArgs args)
        {
            _packetReceived++;
            _totalReceivedBytes += args.Data != null ? (uint)args.Data.Length : 0;
            if (DatagramReceived != null)
            {
                DatagramReceived(args.IP, args.Port, args.Data);
            }
            
            int offset=0,length=args.Data.Length;

            //TODO 此处有问题
            while (offset < length)
            {
                byte[] buffer = new byte[length - offset];
                Array.Copy(args.Data, offset, buffer, 0, buffer.Length);
                //TODO 
                AbsRTCPPackage pack = AbsRTCPPackage.Parse(buffer);
                //响应RTP数据

                if (pack != null && MessageReceived != null)
                {
                    offset += pack.Length;
                    MessageReceived(args.IP, args.Port, pack);
                }
                else
                {
                    offset += buffer.Length;
                }
            }
        }

        /// <summary>
        /// 发送请求消息,此方法为高级方法。
        /// </summary>
        /// <param name="host"></param>
        /// <param name="port"></param>
        /// <param name="pack"></param>
        /// <remarks></remarks>
        public virtual void SendMessage(string host, int port, AbsRTCPPackage pack)
        {
            byte[] buffer = pack.Pack();
            _totalSendBytes += (ulong)buffer.Length;
            _packetSendCount++;
            _socket.SendTo(buffer, host, port);
            if (MessageSend != null)
            {
                MessageSend(host, port, pack);
            }
        }
    }
    /// <summary>
    /// RTCP消息回调
    /// </summary>
    /// <param name="host">主机地址</param>
    /// <param name="port">主机端口</param>
    /// <param name="rp">协议包</param>
    public delegate void RTCPMessageTransmit(string host, int port, AbsRTCPPackage rp);
    /// <summary>
    /// RTCP混合消息回调
    /// </summary>
    /// <param name="ip"></param>
    /// <param name="port"></param>
    /// <param name="protocol"></param>
    /// <param name="channel"></param>
    /// <param name="pack"></param>
    public delegate void RTCPMessageTransmitMix(string ip, int port, string protocol, byte channel, AbsRTCPPackage pack);
}
